package com.loooooo.pm2024.modules.pm.service;


import com.loooooo.pm2024.data.BaseSelector;
import com.loooooo.pm2024.data.Result;
import com.loooooo.pm2024.exception.MyBaseException;
import com.loooooo.pm2024.modules.pm.bo.IssueSummaryResult;
import com.loooooo.pm2024.modules.pm.mapper.IssueMapper;
import com.loooooo.pm2024.modules.pm.model.*;
import com.loooooo.pm2024.modules.pm.selector.*;
import com.loooooo.pm2024.modules.search.IssueIndexer;
import com.loooooo.pm2024.modules.sys.mapper.UxDao;
import com.loooooo.pm2024.modules.sys.model.PrettyUser;
import com.loooooo.pm2024.modules.sys.model.User;
import com.loooooo.pm2024.modules.sys.selector.UserSelector;
import com.loooooo.pm2024.modules.sys.service.UserService;
import com.loooooo.pm2024.security.SecurityUtils;
import com.loooooo.pm2024.service.IdService;
import com.loooooo.pm2024.utils.DateUtils;
import com.loooooo.pm2024.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class IssueService {

    @Autowired
    IssueMapper issueMapper;
    @Autowired
    IdService idService;
    @Autowired
    TaskService taskService;
    @Autowired
    IssueCommentService commentService;
    @Autowired
    AttachmentService attachmentService;
    @Autowired
    TransactionTemplate transactionTemplate;
    @Autowired
    UserService userService;

    public Issue get(Long id) {
        return get(id, null);
    }


    public Issue get(Long id, IssueSelector selector) {
        Issue issue = issueMapper.get(id);
        if (issue != null && selector != null) {
            if (Objects.equals(1, selector.getWithTaskList())) {
                TaskSelector taskSelector = new TaskSelector();
                taskSelector.getTarget().setIssueId(issue.getId());
                List<Task> taskList = taskService.list(taskSelector);
                issue.setTaskList(taskList.stream().filter(x -> Objects.equals(issue.getId(), x.getIssueId())).collect(Collectors.toList()));
            }
            if (Objects.equals(1, selector.getWithCommentList())) {
                IssueCommentSelector commentSelector = new IssueCommentSelector();
                commentSelector.getTarget().setBusinessId(issue.getId());
                List<IssueComment> commentList = commentService.list(commentSelector);
                issue.setCommentList(commentList);
            }
            if (Objects.equals(1, selector.getWithAttachmentList())) {
                AttachmentSelector attachmentSelector = new AttachmentSelector();
                attachmentSelector.getTarget().setIssueId(issue.getId());
                List<Attachment> attachmentList = attachmentService.list(attachmentSelector);
                issue.setAttachmentList(attachmentList);
            }
            if (Objects.equals(1, selector.getWithChildren())) {
                IssueSelector taskSelector = new IssueSelector();
                taskSelector.getTarget().setParentId(issue.getParentId());
                List<Issue> taskList = list(taskSelector);
                issue.setItemList(taskList);
            }
        }
        return issue;
    }

    public List<Issue> list(IssueSelector selector) {
        if (selector != null) {
            if (!StringUtils.hasText(selector.getOrderBy())) {
                selector.setOrderBy("smart");
            }
            if ("smart".equalsIgnoreCase(selector.getOrderBy())) {
                long now = System.currentTimeMillis();
                StringBuilder sb = new StringBuilder();
                sb.append("(case when hung=0 then ");
                //1 未完且有预计完成时间的  2 完且有预计完成时间的 3，完成的

                sb.append(String.format("(case when status<3 then " +
                        "(case when ifnull(expectedFinishTime,0)>1000 then expectedFinishTime else createdAt+%s end) " +
                        " else createdAt+%s end)", 1000L * 3600 * 24 * 365 * 5, 1000L * 3600 * 24 * 365 * 15));

                //sb.append(String.format( " (case when ifnull(expectedFinishTime,0)>1000 then expectedFinishTime else createdAt+%s end) ",1000L*3600*24*365*10));
                sb.append(" else ");
                //挂起的最后 10年
                sb.append(String.format("createdAt+%s", 1000L * 3600 * 24 * 365 * 20));
                //sb.append(now+1000L*3600*24*365*10);

                sb.append("  end),showIndex");
                selector.setOrderBy(sb.toString());
                //selector.setOrderBy(String.format("(case when hung=0 and status<4 then (case when ifnull(expectedFinishTime,0)>=1000 then expectedFinishTime else %s end) else %s+createdAt end) ", now + 1000L * 3600 * 24 * 365, now + 1000L * 3600 * 24 * 365));
            }
        }
        List<Issue> list = issueMapper.select(selector);
        if (list.size() > 0) {
            if (Objects.equals(1, selector.getWithTaskList())) {
                TaskSelector taskSelector = new TaskSelector();
                taskSelector.setIssueIdList(list.stream().map(x -> x.getId()).distinct().collect(Collectors.toList()));
                List<Task> taskList = taskService.list(taskSelector);
                if (taskList.size() > 0) {
                    for (Issue issue : list) {
                        issue.setTaskList(taskList.stream().filter(x -> Objects.equals(issue.getId(), x.getIssueId())).collect(Collectors.toList()));
                        if (issue.getTaskList().size() > 0 && Objects.equals(true, issue.getTimeout())) {
                            issue.getTaskList().stream().filter(x -> x.getStatus() < 4).forEach(x -> x.setTimeout(true));
                        }
                    }
                }
            }
            if (Objects.equals(1, selector.getWithCommentList())) {
                IssueCommentSelector taskSelector = new IssueCommentSelector();
                taskSelector.setBusinessIdList(list.stream().map(x -> x.getId()).distinct().collect(Collectors.toList()));
                List<IssueComment> taskList = commentService.list(taskSelector);
                if (taskList.size() > 0) {
                    for (Issue issue : list) {
                        issue.setCommentList(taskList.stream().filter(x -> Objects.equals(issue.getId(), x.getBusinessId())).collect(Collectors.toList()));
                    }
                }
            }
            if (Objects.equals(1, selector.getWithChildren())) {
                IssueSelector taskSelector = new IssueSelector();
                taskSelector.getTarget().setTop(0);
                taskSelector.setPageNo(null);
                taskSelector.setPageSize(null);
                taskSelector.setWithTaskList(1);
                taskSelector.setWithCommentList(1);
                taskSelector.setWithPrettyActor(1);
                taskSelector.setParentIdList(list.stream().map(x -> x.getId()).distinct().collect(Collectors.toList()));
                List<Issue> taskList = list(taskSelector);
                if (taskList.size() > 0) {
                    for (Issue issue : list) {
                        issue.setItemList(taskList.stream().filter(x -> Objects.equals(issue.getId(), x.getParentId())).collect(Collectors.toList()));
                    }
                }
            }


            if (Objects.equals(1, selector.getWithPrettyActor())) {
                List<Long> userIdList = new ArrayList<>();
                for (Issue issue : list) {
                    appendIf(userIdList, issue.getCreatedBy());
                    appendIf(userIdList, issue.getUpdatedBy());
                    appendIf(userIdList, issue.getOwnerId());
                    appendIf(userIdList, issue.getPublishedBy());
                    if (issue.getTaskList() != null) {
                        for (Task task : issue.getTaskList()) {
                            appendIf(userIdList, task.getOwnerId());
                            appendIf(userIdList, task.getHungBy());
                            appendIf(userIdList, task.getCommittedBy());
                            appendIf(userIdList, task.getApprovedBy());
                            appendIf(userIdList, task.getCreatedBy());
                        }
                    }
                    if (issue.getCommentList() != null) {
                        for (IssueComment task : issue.getCommentList()) {
                            appendIf(userIdList, task.getOwnerId());
                            appendIf(userIdList, task.getCreatedBy());
                        }
                    }
                }
                userIdList = userIdList.stream().distinct().collect(Collectors.toList());
                UserSelector userSelector = new UserSelector();
                userSelector.setIdList(userIdList);
                List<User> userList0 = userService.list(userSelector);
                List<PrettyUser> userList = userList0.stream().map(x -> PrettyUser.build(x)).collect(Collectors.toList());
                for (Issue issue : list) {
                    issue.setCreatedByUser(findIf(userList, issue.getCreatedBy()));
                    issue.setUpdatedByUser(findIf(userList, issue.getUpdatedBy()));
                    issue.setOwnerUser(findIf(userList, issue.getOwnerId()));
                    issue.setPublishByUser(findIf(userList, issue.getPublishedBy()));
                    if (issue.getTaskList() != null) {
                        for (Task task : issue.getTaskList()) {
                            task.setCreatedByUser(findIf(userList, task.getCreatedBy()));
                            task.setUpdatedByUser(findIf(userList, task.getUpdatedBy()));
                            task.setCommittedByUser(findIf(userList, task.getCommittedBy()));
                            task.setOwnerUser(findIf(userList, task.getOwnerId()));
                        }
                    }
                    if (issue.getCommentList() != null) {
                        for (IssueComment task : issue.getCommentList()) {
                            task.setCreatedByUser(findIf(userList, task.getCreatedBy()));
                            task.setUpdatedByUser(findIf(userList, task.getUpdatedBy()));
                        }
                    }
                }
            }
        }
        return list;
    }

    void appendIf(List<Long> list, Long id) {
        if (id != null) list.add(id);
    }

    PrettyUser findIf(List<PrettyUser> list, Long id) {
        if (id == null) return null;
        return list.stream().filter(x -> Objects.equals(x.getId(), id)).findAny().orElse(null);
    }

    public int count(IssueSelector selector) {
        return issueMapper.count(selector);
    }

    public int update(Issue issue, Integer published, List<Long> toList) {
        int r = update(issue);
        long now = System.currentTimeMillis();
        Long userId = SecurityUtils.loginedUserId();

        if (Objects.equals(1, published)) {
            issue.setPublished(1);
            issue.setPublishedBy(userId);
            issue.setPublishedAt(now);
            update(issue);
        }

        if (toList != null) {
            for (Long u : toList) {
                take(issue.getId(), null, u);
            }
        }
        return r;
    }

    public int update(Issue issue) {
        long now = System.currentTimeMillis();
        issue.setUpdatedAt(now);
        Long userId = SecurityUtils.loginedUserId();
        issue.setUpdatedBy(userId);


        if (issue.getId() == null || issue.isNewEntity() || issue.getId() <= 0L) {
            if (userId == null) {
                MyBaseException.throwMe(10401, "未登录");
            }
            //641356099362099200
//            int hour = LocalDateTime.now().getHour();
//            if (hour >= 20 || hour < 9) {
//                if (!Objects.equals(641356099362099200L, userId)) {
//                    MyBaseException.throwMe(10403, "晚上20:00到次日09:00之间不能创建。");
//                }
//            }
            if (issue.getId() == null || issue.getId() <= 0L) {
                issue.setId(idService.nextId());
            }
            issue.setCreatedAt(now);
            issue.setCreatedBy(userId);

            if (issue.getParentId() != null && issue.getParentId() > 0) {
                uxDao.executeSQL(String.format("update tbl_task set hung=1,estimatedTime=0 where issueId=%s",issue.getParentId()));
            }

            //if (Objects.equals(issue.getPublished(), 1)) publish = true;
            issueMapper.insert(issue);
            issueMapper.updateChildren();
        }
//        if (publish) {
//            issue.setPublished(1);
//            issue.setPublishedBy(userId);
//            issue.setPublishedAt(now);
//        }
        try {
            index(issue);
        } catch (Exception ex) {

        }
        return issueMapper.update(issue);
    }

    public int updateMulti(List<Issue> issueList) {

        return transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {
                int r = 0;
                for (Issue issue : issueList) {
                    r += update(issue);
                }
                return r;
            }
        });
    }

    public Task take(Long issueId, Task task) {
        return take(issueId, task, null);
    }

    public List<Task> assign(Long issueId, Task task, List<Long> toList) {
        List<Task> ls = new ArrayList<>();
        if (toList != null) {
            for (Long u : toList) {
                Task t = take(issueId, task, u);
                if (t != null) ls.add(t);
            }
        }
        return ls;
    }

    public Task take(Long issueId, Task task, Long assignTo) {
        Issue issue = get(issueId);
        if (issue == null) return null;
        long now = System.currentTimeMillis();
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }
        if (assignTo == null) assignTo = userId;
        System.out.println("issuetake userid=" + userId);
        TaskSelector taskSelector = new TaskSelector();
        taskSelector.getTarget().setIssueId(issue.getId());
        taskSelector.getTarget().setOwnerId(assignTo);
        List<Task> ls = taskService.list(taskSelector);
        if (ls.size() > 0) {
            System.out.println("issuetake exists");
            return ls.get(0);
        }
        if (task == null) task = new Task();
        task.setIssueId(issue.getId());
        task.setOwnerId(assignTo);
        task.setSubject(issue.getSubject());
        task.setUrgent(issue.getUrgent());
        task.setPriority(issue.getPriority());
        if (issue.task() == 0) {
            task.setStandalone(1);
            task.setDependent(0);
        }
        issue.setStatus(2);
        issue.setTask(issue.task() + 1);
        Task task1 = task;
        System.out.println("issuetake task=" + JsonUtils.serializeToString(task));
        int r = transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {
                update(issue);
                return taskService.update(task1);
            }
        });
        if (r > 0)
            return task1;
        return null;
    }

    public int hang(Long issueId, Integer hung, String reason) {
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }

        long now = System.currentTimeMillis();
        Issue issue = get(issueId);
        if (issue == null) return -1;
        if (Objects.equals(1, hung)) {
            issue.setHung(1);
            issue.setHungAt(now);
            issue.setHungBy(userId);
            issue.setHungReason(reason);
        } else {
            issue.setHung(0);
            issue.setHungAt(0L);
            issue.setHungBy(0L);
            issue.setHungReason(reason);
        }

        TaskSelector taskSelector = new TaskSelector();
        taskSelector.getTarget().setIssueId(issue.getId());
        //taskSelector.getTarget().setOwnerId(userId);
        List<Task> ls = taskService.list(taskSelector);

        int r = transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {
                for (Task task : ls) {
                    taskService.hang(task, hung, reason);
                }
                return update(issue);
            }
        });

        return r;

    }

    public int publish(Long issueId, Integer publish) {
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }

        long now = System.currentTimeMillis();
        Issue issue = get(issueId);
        if (issue == null || !Objects.equals(0, issue.getStatus())) return -1;

        if (Objects.equals(publish, 1)) {
            issue.setPublished(1);
            issue.setPublishedAt(now);
            issue.setPublishedBy(userId);
            issue.setStatus(1);
        } else {
            issue.setPublished(0);
            issue.setPublishedAt(0L);
            issue.setPublishedBy(0L);
            issue.setStatus(0);
        }
        return update(issue);

    }

    @Autowired
    UxDao uxDao;

    public int urgent(Long issueId, Integer urgent, String reason) {
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }

        long now = System.currentTimeMillis();
        Issue issue = get(issueId);
        if (issue == null) return -1;
        issue.setUrgent(urgent);

        TaskSelector taskSelector = new TaskSelector();
        taskSelector.getTarget().setIssueId(issue.getId());
        taskSelector.getTarget().setOwnerId(userId);
        List<Task> ls = taskService.list(taskSelector);

        int r = transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {

                return uxDao.executeSQL(String.format("update tbl_task a inner join tbl_issue b on (a.issueId=b.id) set a.urgent=%s,b.urgent=%s where b.id=%s or b.parentId=%s", issue.getUrgent(), issue.getUrgent(), issue.getId(), issue.getId()));

//                uxDao.executeSQL(String.format("update tbl_issue set urgent=%s where id=%s or parentId=%s", issue.getUrgent(), issue.getId(), issue.getId()));
//                for (Task task : ls) {
//                    task.setUrgent(issue.getUrgent());
//                    taskService.update(task);
//                }
//                return update(issue);
            }
        });

        return r;

    }

    public int commit(Long issueId, Integer commit) {
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }

        long now = System.currentTimeMillis();
        Issue issue = get(issueId);
        if (issue == null) return -1;
        if (Objects.equals(0, commit)) {
            issue.setStatus(2);
            issue.setCommittedAt(0L);
        } else {
            //if (!Objects.equals(1, issue.getPublished())) return 0;
            TaskSelector taskSelector = new TaskSelector();
            taskSelector.getTarget().setIssueId(issue.getId());
            //taskSelector.getTarget().setOwnerId(userId);
            List<Task> ls = taskService.list(taskSelector);
            if (ls.size() > 0 && ls.stream().noneMatch(x -> !Objects.equals(4, x.getStatus()))) {
                issue.setStatus(3);
                issue.setCommittedAt(now);
            }
        }

        return update(issue);

    }

    public int complete(Long issueId, Integer complete) {
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }

        long now = System.currentTimeMillis();
        Issue issue = get(issueId);
        if (issue == null) return -1;
        if (!Objects.equals(1, issue.getPublished())) return 0;
        if (Objects.equals(1, complete)) {
            if (!Objects.equals(3, issue.getPublished())) return 0;
            issue.setStatus(4);
        } else {
            if (!Objects.equals(4, issue.getPublished())) return 0;
            issue.setStatus(3);
        }

        return update(issue);

    }

    public int approve(Long issueId, Integer approve, String reason) {
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "未登录");
        }

        long now = System.currentTimeMillis();
        Issue issue = get(issueId);
        if (issue == null) return -1;
        //if (!Objects.equals(1, issue.getPublished())) return 0;
        TaskSelector taskSelector = new TaskSelector();
        taskSelector.getTarget().setIssueId(issue.getId());
        List<Task> ls = taskService.list(taskSelector);
        if (Objects.equals(1, approve)) {
            if (!Objects.equals(3, issue.getStatus())) return 0;
            issue.setStatus(4);
            issue.setApproved(1);
            issue.setApprovedAt(now);
            issue.setApprovedBy(userId);
            issue.setApprovedReason(reason);
            ls.forEach(x -> x.setStatus(5));
        } else {
            //if (!Objects.equals(4, issue.getStatus())) return 0;
            issue.setStatus(2);
            issue.setApproved(-1);
            issue.setApprovedAt(now);
            issue.setApprovedBy(userId);

            issue.setApprovedReason(reason);
            ls.forEach(x -> x.setStatus(1));
        }
        IssueComment comment = null;
        if (StringUtils.hasText(reason)) {
            comment = new IssueComment();
            comment.setIssueId(issue.getId());
            comment.setOwnerId(userId);
            comment.setType("issue");
            comment.setBusinessId(issue.getId());
            comment.setSubject("审核不通过");
            comment.setContent(reason);
        }
        IssueComment issueComment = comment;
        int r = transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {
                ls.forEach(x -> taskService.update(x));
                if (issueComment != null) {
                    commentService.update(issueComment);
                }
                return update(issue);
            }
        });
        return r;

    }

    public int delete(Long issueId, Integer value) {
        return hang(issueId,1,"删除");
//        Long userId = SecurityUtils.loginedUserId();
//        if (userId == null) {
//            MyBaseException.throwMe(10401, "未登录");
//        }
//
//        long now = System.currentTimeMillis();
//        Issue issue = get(issueId);
//        if (issue == null) return -1;
//
//        issue.setDeleted(1);
//        return update(issue);

    }

    public Result search(String keyword) {

        Result rs = IssueIndexer.search(keyword, "/image2/pm2024/search/index");
        List<String> idLists = (List<String>) rs.getData();
        List<Long> idList = idLists.stream().map(x -> Long.valueOf(x)).collect(Collectors.toList());
        IssueSelector selector = new IssueSelector();
        selector.setIdList(idList);
        selector.setPageSize(idList.size());
        rs.setData(list(selector));
        return rs;
    }

    public int index() {
        IssueSelector selector = new IssueSelector();
        List<Issue> ls = list(selector);
        try {
            IssueIndexer.index(ls, "/image2/pm2024/search/index");
        } catch (IOException e) {

        }
        return ls.size();
    }

    public int index(Issue issue) {
        try {
            IssueIndexer.index(Arrays.asList(issue), "/image2/pm2024/search/index");
        } catch (IOException e) {

        }
        return 1;
    }


    public int workload(Long userId, Long date, Integer type) {
        if (date == null) date = System.currentTimeMillis();
        Long d1 = DateUtils.localDate2Long(DateUtils.toLocalDateTime(date).toLocalDate().plusDays(1)) - 1;
        double load1 = issueMapper.workload(d1, userId);
        if (!Objects.equals(1, type)) {
            Long d0 = DateUtils.localDate2Long(DateUtils.toLocalDateTime(date).toLocalDate()) - 1;
            double load0 = issueMapper.workload(d0, userId);
            return (int) (load1 - load0);
        }
        return (int) load1;
    }

    @Autowired
    WorkDayService workDayService;

    public int hungIfTimeout() {
        IssueSelector selector = new IssueSelector();
        selector.getTarget().setHung(0);
        selector.setStatusList(Arrays.asList(1, 2));
        List<Issue> list = list(selector);
        if (list.size() == 0) return 0;

        long min = list.stream().mapToLong(x -> x.getCreatedAt()).min().orElse(System.currentTimeMillis()) - 1000L * 3600 * 24;
        long max = System.currentTimeMillis();
        WorkDaySelector workDaySelector = new WorkDaySelector();
        workDaySelector.setDateAfter(min);
        List<WorkDay> dayList = workDayService.list(workDaySelector);
        dayList.sort((a, b) -> Long.compare(a.getDate(), b.getDate()));
        int r = 0;
        LocalDate today = LocalDate.now();
        LocalDateTime now = LocalDateTime.now();
        for (Issue issue : list) {
            if (issue.getTimeLimit() == null || issue.getTimeLimit() < 1) continue;
            //当天离下班的时间,要看当天是否工作日。

            LocalDateTime createdDateTime = DateUtils.toLocalDateTime(issue.getCreatedAt());
            long timeLimit = issue.getTimeLimit();
            LocalDate createdDate = createdDateTime.toLocalDate();

            if (createdDateTime.getHour() < 18) {
                WorkDay workDay = dayList.stream().filter(x -> Objects.equals(x.getDate(), DateUtils.localDate2Long(createdDate))).findAny().orElse(null);

                boolean work = true;
                if (workDay == null) {
                    work = Objects.equals(workDay.getValue(), 1);
                } else {
                    work = createdDate.getDayOfWeek().getValue() < 6;
                }
                if (work) {
                    long delta = DateUtils.localDateTime2Long(createdDateTime.withHour(18)) - issue.getCreatedAt();
                    timeLimit -= delta / (1000 * 60);
                }
                if (timeLimit <= 0) {
                    issue.setHung(1);
                    continue;
                }
            }
            //如果

            long minutes = 0;
            for (LocalDate startAt = createdDate.plusDays(1); !startAt.isAfter(today); startAt = startAt.plusDays(1)) {
                LocalDate currDate = startAt;
                WorkDay workDay = dayList.stream().filter(x -> Objects.equals(x.getDate(), DateUtils.localDate2Long(currDate))).findAny().orElse(null);

                boolean work = true;
                if (workDay == null) {
                    work = Objects.equals(workDay.getValue(), 1);
                } else {
                    work = createdDate.getDayOfWeek().getValue() < 6;
                }
                if (work) {
                    if (currDate.isEqual(today) && now.getHour() < 18) {
                        long delta = DateUtils.localDateTime2Long(now.withHour(18)) - System.currentTimeMillis();
                        minutes += (60 * 8 - delta / (1000 * 60));
                    } else {
                        minutes += 60 * 8;
                    }
                }

            }
            if (minutes >= timeLimit) {
                issue.setHung(1);
            }

        }
        list = list.stream().filter(x -> Objects.equals(1, x.getHung())).collect(Collectors.toList());
        for (Issue issue : list) {
            r += update(issue);
        }
        return r;
    }

    public static void main(String[] args) {
        LocalDateTime time1 = LocalDateTime.now();
        LocalDateTime time2 = time1.withHour(11);
        System.out.println(time1);
        System.out.println(time2);
        System.out.println(time1.compareTo(time2));
    }


    public SummaryResponse summaryAdv(IssueSelector issueSelector0) {

        if (issueSelector0 == null) issueSelector0 = new IssueSelector();
        //issueSelector0.setStatusList(Arrays.asList(1, 2, 3, 4, 5));


        IssueSelector issueSelector = JsonUtils.deserializeFromString(JsonUtils.serializeToString(issueSelector0), IssueSelector.class);

        issueSelector.setColumnList(Arrays.asList("status", "count(0) `count`"));
        issueSelector.setGroupByList(Arrays.asList("status"));
        issueSelector.setOrderBy("status");
        issueSelector.getTarget().setHung(0);

        long startAt = System.currentTimeMillis();
        issueSelector.fieldList().add(new BaseSelector.Field("status"));

        List<IssueSummaryResult> ls = issueMapper.summary(issueSelector);

        long endAt = System.currentTimeMillis();

        System.out.println(String.format("time: %s, rs=%s", endAt - startAt, JsonUtils.serializeToString(ls)));
        SummaryResponse response = new SummaryResponse();

        issueSelector.setGroupByList(null);
        issueSelector.setColumnList(null);
        issueSelector.setHavingList(null);

        for (IssueSummaryResult data : ls) {
            SummaryResponse.SummaryItem item = new SummaryResponse.SummaryItem();
            item.setName("" + data.getResult().get("status").asText());
            item.setCount(data.getCount());
            IssueSelector selector = JsonUtils.deserializeFromString(JsonUtils.serializeToString(issueSelector), IssueSelector.class);
            selector.setStatusList(null);
            selector.setOrderBy("id desc");
            selector.getTarget().setStatus(Integer.valueOf(data.getResult().get("status").asText()));
            item.setSelector(selector);
            response.itemList().add(item);
        }

        issueSelector.getTarget().setHung(1);
        issueSelector.setGroupByList(null);
        int count = issueMapper.count(issueSelector0);
        SummaryResponse.SummaryItem item = new SummaryResponse.SummaryItem();
        item.setName("hung");
        item.setCount(count);
        IssueSelector selector = JsonUtils.deserializeFromString(JsonUtils.serializeToString(issueSelector), IssueSelector.class);
        selector.setStatusList(null);
        selector.setOrderBy("id desc");
        item.setSelector(selector);
        response.itemList().add(item);

        return response;
    }

    public static class SummaryResponse implements Serializable {
        public List<SummaryItem> getItemList() {
            return itemList;
        }

        public List<SummaryItem> itemList() {
            if (itemList == null) itemList = new ArrayList<>();
            return itemList;
        }

        public void setItemList(List<SummaryItem> itemList) {
            this.itemList = itemList;
        }

        private List<SummaryItem> itemList;

        public static class SummaryItem implements Serializable {
            private String name;
            private String title;

            private Integer count;

            private String description;
            private Object selector;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getTitle() {
                return title;
            }

            public void setTitle(String title) {
                this.title = title;
            }

            public String getDescription() {
                return description;
            }

            public void setDescription(String description) {
                this.description = description;
            }

            public Object getSelector() {
                return selector;
            }

            public void setSelector(Object selector) {
                this.selector = selector;
            }

            public Integer getCount() {
                return count;
            }

            public void setCount(Integer count) {
                this.count = count;
            }
        }
    }

}
